#pragma once

#include "ConsolePrerequisites.h"
#include "LexicalCast.h"

class IValue
{
public:
	virtual csString	Get() const = 0;
	virtual void		Set( const csString & v ) = 0;
	virtual csString	Default() = 0;
	virtual void		Reset() = 0;
};

template<typename T>
class CValue : public IValue
{
public:

	typedef T value_type;
	typedef void (changed_callback)( const value_type & changed_value );

	CValue( const value_type & v, changed_callback * cb = NULL )
	{
		m_CurrentValue = v;
		m_DefaultValue = v;
		m_pCallback = cb;
	}

	virtual csString	Get() const
	{
		return LexicalCast<csString>( m_CurrentValue );
	}

	virtual void		Set( const csString & v )
	{
		value_type before = m_CurrentValue;
		m_CurrentValue = LexicalCast<T>( v );
		if ( before != m_CurrentValue && m_pCallback )
			m_pCallback(m_CurrentValue);

	}

	virtual std::string	Default()
	{
		return LexicalCast<std::string>( m_DefaultValue );
	}

	virtual void		Reset()
	{
		value_type before = m_CurrentValue;
		m_CurrentValue = m_DefaultValue;
		if ( before != m_CurrentValue && m_pCallback )
			m_pCallback(m_CurrentValue);
	}

	//////////////////////////////////////////////////////////////////////////


	// operators
	operator			const value_type() const
	{
		return m_CurrentValue;
	}
	void 				operator = ( const value_type & v )
	{
		value_type before = m_CurrentValue;
		m_CurrentValue = v;
		if ( before != m_CurrentValue && m_pCallback )
			m_pCallback(m_CurrentValue);
	}


private:
	value_type	m_CurrentValue;
	value_type	m_DefaultValue;
	changed_callback *	m_pCallback;

};


